////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Microsoft Corporation.  All rights reserved.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
// Portions Copyright (c) 2012 Kentaro Sekimoto  All rights reserved.
////////////////////////////////////////////////////////////////////////////

#include <tinyhal.h>

#if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
#pragma arm section rwdata = "g_AvailableFSInterfaces"
#endif

#define SD_INSERT_PIN   0xa3

extern FILESYSTEM_DRIVER_INTERFACE g_FAT32_FILE_SYSTEM_DriverInterface;
extern STREAM_DRIVER_INTERFACE g_FAT32_STREAM_DriverInterface;

// SD CARD
extern struct BlockStorageDevice  g_SD_BS;
extern struct IBlockStorageDevice g_SD_BS_DeviceTable;
extern struct BLOCK_CONFIG        g_SD_BS_Config;
//FileSystemVolume g_SD_FS;
// NOR Flash
//extern struct BlockStorageDevice  g_WXMP3PLCD_FM3_BS;
//FileSystemVolume g_WXMP3PLCD_FM3_NOR_FS;
// Serial Flash
//extern struct BlockStorageDevice g_SerialFlash_Device;
//FileSystemVolume g_WXMP3PLCD_FM3_SERIAL_FS;
// USB Host
//extern struct BlockStorageDevice g_WXMP3PLCD_FM3_USB_Device;
//FileSystemVolume g_WXMP3PLCD_FM3_USB_FS;

void SD_InsertEjectIsr(GPIO_PIN Pin, BOOL PinState, void* Param);

void FS_AddVolumes()
{
    CPU_GPIO_EnableInputPin(SD_INSERT_PIN, TRUE, SD_InsertEjectIsr, GPIO_INT_EDGE_BOTH, RESISTOR_PULLUP);
//    FileSystemVolumeList::AddVolume(&g_WXMP3PLCD_FM3_NOR_FS, "ROOT", 0, 0, &g_FAT32_STREAM_DriverInterface, &g_FAT32_FILE_SYSTEM_DriverInterface, &g_WXMP3PLCD_FM3_BS, 1, FALSE);
//    FileSystemVolumeList::AddVolume(&g_WXMP3PLCD_FM3_SERIAL_FS, "ROOT", 0, 0, &g_FAT32_STREAM_DriverInterface, &g_FAT32_FILE_SYSTEM_DriverInterface, &g_SerialFlash_Device, 1, FALSE);
//    FileSystemVolumeList::AddVolume(&g_WXMP3PLCD_FM3_USB_FS, "U", 0, 0, &g_FAT32_STREAM_DriverInterface, &g_FAT32_FILE_SYSTEM_DriverInterface, &g_WXMP3PLCD_FM3_USB_Device, 1, FALSE);
//    FileSystemVolumeList::AddVolume(&g_SD_FS, "SD", 0, 0, &g_FAT32_STREAM_DriverInterface, &g_FAT32_FILE_SYSTEM_DriverInterface, &g_SD_BS, 0, FALSE);
}

void FS_MountRemovableVolumes()
{
    if (!CPU_GPIO_GetPinState(SD_INSERT_PIN)) {
        if (BlockStorageList::AddDevice(&g_SD_BS, &g_SD_BS_DeviceTable, &g_SD_BS_Config, TRUE)) {
            FS_MountVolume("SD", 0, 0, &g_SD_BS);
        }
    }
}

FILESYSTEM_INTERFACES g_AvailableFSInterfaces[] =
{
    { &g_FAT32_FILE_SYSTEM_DriverInterface, &g_FAT32_STREAM_DriverInterface },
};

void SD_InsertEjectIsr(GPIO_PIN Pin, BOOL PinState, void* Param)
{
    if (!PinState) {
        if (BlockStorageList::AddDevice(&g_SD_BS, &g_SD_BS_DeviceTable, &g_SD_BS_Config, TRUE)) {
            FS_MountVolume("SD", 0, 0, &g_SD_BS);
        }
    } else {
        FS_UnmountVolume(&g_SD_BS);
        BlockStorageList::RemoveDevice(&g_SD_BS, TRUE);
    }
}

//const size_t g_InstalledFSCount = ARRAYSIZE(g_AvailableFSInterfaces);
const size_t g_InstalledFSCount = 1;

#if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
#pragma arm section rwdata
#endif
